'''
Created on Apr 12, 2012

@author: dolphinigle
'''

import random
import fractions
import util
import prime_gen

def GenKey():
  '''
  Returns (p, g, x, y)
  '''
  p = prime_gen.Generate(161, 170)
  g = random.randrange(2, p-1)
  x = random.randrange(2, p-1)
  y = util.ModExp(g, x, p)
  return (p, g, x, y)

def Sign(p, g, x, text):
  '''
  text is given as hex string
  
  Returns ctext as (String, String) denoting (a, b)
  '''
  print 'Signing...'
  while True:
    k = random.randrange(2, p-1)
    if fractions.gcd(k, p-1) == 1:
      break
  
  r = util.ModExp(g, k, p)
  s = util.HexToInt(text) - x * r
  s %= (p-1)
  if s < 0:
    s += (p-1)
  s *= util.ModInverse(k, p-1)
  s %= (p-1)
  
  if s == 0:
    return Sign(p, g, x, text)
  
  return util.ToHex(180, r) + util.ToHex(180, s)

def Verify(p, g, y, signature, text):
  '''
  ctext is given as a hex string key
  
  returns True if they match, false otherwise
  '''
  print 'Verifying...'
  r = util.HexToInt(signature[:45])
  s = util.HexToInt(signature[45:])
  
  left = util.ModExp(g, util.HexToInt(text), p)
  right = (util.ModExp(y, r, p) * util.ModExp(r, s, p)) % p
  return left == right
  
